import requests
import json
from datetime import datetime
from distutils.util import strtobool
from sqlalchemy.orm import Session
from core.response import resp_500
from core.logger import logger
from common.notice_tools import NoticeTools
from common.welab_k8s.k8s_pod import K8sPod
from common.welab_k8s import init_k8s
from common.welab_k8s.k8s_utils import K8sUtils
from app.notice_center.models.nc_n9e_alarm_record import NCN9eAlarmRecord
from app.notice_center.handlers.nc_n9e_alarm_handler import NCN9eAlarmHandler
from setting import config



class NCN9eCallbackNodeMemHandler():
    """  Self Healing Handler
    """
    def __init__(self):
        init_k8s()
        self.token = config.FSR_NODE_MEM_TOKEN
        self.k8s_pod = K8sPod()
        self.notice_tools = NoticeTools()


    def post_nc_n9e_heal_node_mem(self, db: Session, data: dict, token: str):
        try:
            logger.info(f"node mem 收到回调告警信息=>{data}")

            alarm_data = {
                "status": "resolved" if data["is_recovered"] else "firing",
                "namespace": "prod",
                "node": data["target_ident"].split("-")[-1]
            }

            # 前期数据判断
            if "" in list(alarm_data.values()):
                # token验证
                logger.error(f"node mem: value is null")
                return False
            
            if self.token != token:
                logger.error(f"node mem: token is error")
                return False
            
            if alarm_data["status"] == "resolved":
                logger.info(f"node mem: status is resolved, do nothing")
                return True
                    
            # 全局维护：不告警、不回调
            nc_n9e_alarm_handler = NCN9eAlarmHandler()
            global_record_info = NCN9eAlarmRecord.get_object_info_for_block_global(db)
            if global_record_info and not nc_n9e_alarm_handler.check_alert_notice_maintain(global_record_info):
                logger.info(f"container cpu usage: block alarm in global maintain")
                return True
                    
            # 处理node节点上的pods
            result = self.handle_node_mem(alarm_data["node"], alarm_data["namespace"])
            if not result:
                logger.error(f"handle node mem failed")
                return False

            logger.info(f"handle node mem success")
        except Exception as e:
            message = f"handle node mem error"
            logger.exception(f"{message} => {e}")
            return resp_500(message)

        return True



    def handle_node_mem(self, node: str, namespace: str):
        """
        理node节点上的pods
        """
        # 获取节点上的pods信息
        pods = self.k8s_pod.list_node_pod(node, namespace)
        if not pods:
            logger.error(f"list node pod failed")
            return False
        
        
        # 获取可以删除的pod
        max_mem_pod = {
            "pod_name": "",
            "mem": 0
        }
        filter_pods = ["welab-authority", "welab-skyscanner", "pangu-app", "finance-repayment"]
        for pod in pods:
            #过滤不能动的pods
            is_filter = False
            for filter_pod in filter_pods:
                if pod.metadata.name.startswith(filter_pod):
                    is_filter = True
                    break
            
            if is_filter:
                continue
                
            # 找一个mem最大的pods
            total_mem = 0
            for container in pod.spec.containers:
                total_mem += K8sUtils.mem_unit_to_G(container.resources.limits.get("memory", "0"))
                
            if total_mem > max_mem_pod["mem"]:
                max_mem_pod["pod_name"] = pod.metadata.name
                max_mem_pod["mem"] = total_mem
        
        pod_name = max_mem_pod["pod_name"]
        if pod_name == "":
            logger.error(f"find pod failed")
            return False
           
           
        # 删除pod
        result = self.k8s_pod.delete_pod_from_namespace(namespace, pod_name)
        if not result:
            message = f"n9e故障自愈 => node:{node}内存太高, 删除pod:{pod_name}失败"
            logger.error(f"delete pod failed => {message}")
        else:
            message = f"n9e故障自愈 => node:{node}内存太高, 删除pod:{pod_name}成功"
            logger.info(f"delete pod success => {message}")

        # 发送处理结果信息到企业微信群
        self.notice_tools.send_wechat_group(message)
        
        return True


